package wang.chunfan.code.netty.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.CountDownLatch;

/**
 * @version 1.0
 * @Author wangchunfan
 * @Date 2020/6/2 13:53
 * 在一个线程中运行
 **/
public class AsyncTimeServerHandler implements Runnable {
    private int port;
    CountDownLatch latch;
    AsynchronousServerSocketChannel asynchronousServerSocketChannel;

    public AsyncTimeServerHandler(int port) {
        this.port = port;
        try {
            // 创建 channel
            asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
            // 绑定监听端口
            asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
            System.out.println("The time server is start in port : " + port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        latch = new CountDownLatch(1);
        // 接收客户端连接
        doAccept();
        try {
            // 因为是异步的，所以在此让线程阻塞，防止服务端执行完退出
            // 在实际项目应用中，不需要启动独立的线程来处理 AsynchronousServerSocketChannel
            // 此处将一直阻塞，服务端没有相应的 latch.countDown，除非发生异常
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void doAccept() {
        // accept 的结果为 socketChannel
        // 它将作为 AcceptCompletionHandler 回调函数中的第一个参数
        asynchronousServerSocketChannel.accept(
                // attachment 参数，为附加对象，传递给回调函数
                this,
                // 用来接收 accept 操作成功的通知消息
                // 相当于回调函数
                new AcceptCompletionHandler());
    }
}
